package com.liaoyoule.multiple.shiro;

import com.liaoyoule.multiple.dao.entity.PermissionEntity;
import com.liaoyoule.multiple.dao.entity.RoleEntity;
import com.liaoyoule.multiple.dao.entity.UserEntity;
import com.liaoyoule.multiple.dto.UserDTO;
import com.liaoyoule.multiple.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Set;


/**
 * Created by cdyoue on 2017/2/20.
 */
public class AuthorRealm extends AuthorizingRealm {
    private static final Logger logger = LoggerFactory.getLogger(AuthorRealm.class);

    @Autowired
    private UserService userService;
    @Override
    @Transactional
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        logger.info("##################执行Shiro权限认证##################");
        //获取当前登录输入的用户名，等价于(String) principalCollection.fromRealm(getName()).iterator().next();
        String loginName = (String)super.getAvailablePrincipal(principalCollection);
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        UserEntity userEntity = new UserEntity();
        userEntity.setEmail(loginName);
        UserDTO user =  userService.listInfo(userEntity);
        if(user == null){
            throw new UnknownAccountException();
        }

        Set<RoleEntity> roles = user.getRoles();
        info.addRoles(new ArrayList(roles));
        roles.forEach(p->{
            Set<PermissionEntity> permissions = p.getPermissions();
            info.addObjectPermissions(new ArrayList(permissions));
        });

        return info;
    }
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        UserEntity userEntity = new UserEntity();
        userEntity.setEmail(token.getUsername());
        UserDTO user =  userService.listInfo(userEntity);

        if(user==null){
            throw new UnknownAccountException();
        }
        //盐，随机数，此随机数也在数据库存储
        String salt = user.getSalt();
        String password =  new SimpleHash("md5",token.getPassword(), ByteSource.Util.bytes(salt),2).toHex();
        AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user.getEmail(),user.getPassword(),ByteSource.Util.bytes(salt),this.getName());
        return authcInfo;
    }


    /**
     * 保存登录名
     */
    private void setSession(Object key, Object value){
        Session session = getSession();
        System.err.println("Session默认超时时间为[" + session.getTimeout() + "]毫秒");
        if(null != session){
            session.setAttribute(key, value);
        }
    }

    private Session getSession(){
        try{
            Subject subject = SecurityUtils.getSubject();
            Session session = subject.getSession(false);
            if (session == null){
                session = subject.getSession();
            }
            if (session != null){
                return session;
            }
        }catch (InvalidSessionException e){

        }
        return null;
    }
}
